﻿using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _19对话框综合示例
{
    public static partial class GemotryTool
    {
        // public static List<Entity> GetArcFrom2Lines(this Line line1, Line line2, double radius,out Arc arc)
        /// <summary>
        /// 给两条直线绘制倒圆角
        /// </summary>
        /// <param name="line1"></param>
        /// <param name="line2"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        public static List<Entity> GetArcFrom2Lines(this Line line1, Line line2, double radius)
        {
            Arc arc = new Arc();
            List<Entity> ents = new List<Entity>();
            Point3dCollection points = new Point3dCollection();
            line1.IntersectWith(line2, Intersect.ExtendBoth, points, IntPtr.Zero, IntPtr.Zero);//获取两条直线的交点
            //判断两条直线是否有交点
            if (points.Count > 0)
            {
                line1 = line1.ModifyLinePoints(points[0]);
                line2 = line2.ModifyLinePoints(points[0]);
                double angleSub = line1.GetAngleFromTwoLines(line2);//获取两条直线的夹角（这里的角度值小于180）
                double angle1 = line1.Angle + angleSub > Math.PI * 2 - 0.0000000001 ? line1.Angle + angleSub - Math.PI * 2 : line1.Angle + angleSub;
                double angle2 = line2.Angle + angleSub > Math.PI * 2 - 0.0000000001 ? line2.Angle + angleSub - Math.PI * 2 : line2.Angle + angleSub;
                //判断哪条直线是逆时针方向的第一条
                if (angle1 < line2.Angle + 0.0000000001 && angle1 > line2.Angle - 0.0000000001)
                {
                    arc = EvaluteArc(points[0], line1.Angle, line2.Angle, angleSub, radius);
                    //if (arc.StartPoint.DistanceTo(line2.StartPoint) <= line2.Length && arc.EndPoint.DistanceTo(line1.StartPoint) <= line1.Length)
                    //{
                        ents.Add(arc);
                        line1.StartPoint = arc.EndPoint;
                        line2.StartPoint = arc.StartPoint;
                        ents.Add(line1);
                        ents.Add(line2);
                    //}

                }
                else if (angle2 < line1.Angle + 0.0000000001 && angle2 > line1.Angle - 0.0000000001)
                {
                    arc = EvaluteArc(points[0], line2.Angle, line1.Angle, angleSub, radius);
                    //if (arc.EndPoint.DistanceTo(line2.StartPoint) <= line2.Length && arc.StartPoint.DistanceTo(line1.StartPoint) <= line1.Length)
                    //{
                        ents.Add(arc);
                        line1.StartPoint = arc.StartPoint;
                        line2.StartPoint = arc.EndPoint;
                        ents.Add(line1);
                        ents.Add(line2);
                   //}
                }
            }

            return ents;
        }


        /// <summary>
        /// 计算圆弧，对第一个角度和第二个角度的顺序是有严格的要求，不能传反
        /// </summary>
        /// <param name="point"></param>
        /// <param name="angle1"></param>
        /// <param name="angle2"></param>
        /// <param name="angleSub"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        private static Arc EvaluteArc(Point3d point, double angle1, double angle2, double angleSub, double radius)
        {
            Arc arc = new Arc();
            arc.Radius = radius;
            arc.Center = point.PolarPoint(angle1 + angleSub / 2, radius / Math.Sin(angleSub / 2));
            arc.StartAngle = angle2 + Math.PI / 2;
            arc.EndAngle = arc.StartAngle + Math.PI - angleSub;
            return arc;
        }

        public static Point3d PolarPoint(this Point3d point, double angle, double distance)
        {
            return new Point3d(point.X + distance * Math.Cos(angle), point.Y + distance * Math.Sin(angle), 0);
        }

        /// <summary>
        /// 根据指定点修改直线的起始点和终止点坐标，起始点坐标为指定点，终止点坐标为直线到指定点距离大的那个
        /// </summary>
        /// <param name="line"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static Line ModifyLinePoints(this Line line, Point3d point)
        {
            line.EndPoint = point.DistanceTo(line.EndPoint) >= point.DistanceTo(line.StartPoint) ? line.EndPoint : line.StartPoint;
            line.StartPoint = point;
            return line;
        }

        /// <summary>
        /// 两条直线之间的夹角
        /// </summary>
        /// <param name="line1"></param>
        /// <param name="line2"></param>
        /// <returns></returns>
        public static double GetAngleFromTwoLines(this Line line1, Line line2)
        {
            Vector2d vec1 = new Vector2d(line1.EndPoint.X - line1.StartPoint.X, line1.EndPoint.Y - line1.StartPoint.Y);
            Vector2d vec2 = new Vector2d(line2.EndPoint.X - line2.StartPoint.X, line2.EndPoint.Y - line2.StartPoint.Y);
            return vec1.GetAngleTo(vec2);
        }
        /// <summary>
        /// 获取直线对复制对象,这个对象不在图形数据库
        /// </summary>
        /// <param name="lineId"></param>
        /// <returns></returns>
        public static Line GetCopyLine(this ObjectId lineId)
        {
            Database db = HostApplicationServices.WorkingDatabase;
            Line line = new Line();
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                Line lineS = (Line)lineId.GetObject(OpenMode.ForRead);
                line.StartPoint = lineS.StartPoint;
                line.EndPoint = lineS.EndPoint;
            }
            return line;
        }
        /// <summary>
        /// 弧度转换为角度
        /// </summary>
        /// <param name="angle"></param>
        /// <returns></returns>
        public static double angleToDegree(this double angle)
        {
            return angle * 180 / Math.PI;
        }
        /// <summary>
        /// 角度转化弧度
        /// </summary>
        /// <param name="degree"></param>
        /// <returns></returns>
        public static double degreeToAngle(this double degree)
        {
            return degree * Math.PI / 180;
        }
        /// <summary>
        /// 获取图形的最大包围框
        /// </summary>
        /// <param name="ents"></param>
        /// <returns></returns>
        public static Extents3d GetExtents3d(this List<Entity> ents)
        {
            Extents3d ext = new Extents3d();
            for (int i = 0; i < ents.Count; i++)
            {
                ext.AddExtents(ents[i].GeometricExtents);
            }
            return ext;
        }
        /// <summary>
        /// 缩放图形
        /// </summary>
        /// <param name="ents"></param>
        /// <param name="scaleFactor"></param>
        /// <param name="point"></param>
        public static void ScacleEnts(this List<Entity> ents,double scaleFactor,Point3d point)
        {
            Matrix3d mt = Matrix3d.Scaling(scaleFactor, point);
            for (int i = 0; i < ents.Count; i++)
            {
                ents[i].TransformBy(mt);
            }
        }
        /// <summary>
        /// 移动图形
        /// </summary>
        /// <param name="ents"></param>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        public static void MoveEnts(this List<Entity> ents, double X, double Y)
        {
            Matrix3d mt = Matrix3d.Displacement(new Vector3d(X, Y, 0));
            for (int i = 0; i < ents.Count; i++)
            {
                ents[i].TransformBy(mt);
            }
        }
    }
}
